/**************************************************************************
 * Copyright (C) 2017-2017  Unisound
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 **************************************************************************
 *
 * Description : uni_iot.h
 * Author      : wufangfang@unisound.com
 * Date        : 2019.09.10
 *
 **************************************************************************/
#ifndef HAL_INC_UNI_IOT_H_
#define HAL_INC_UNI_IOT_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
#include <errno.h>
#include <malloc.h>
#include <math.h>
#include <rtthread.h>

#include "uni_types.h"
#include "uni_cust_config.h"

#define UNI_MEDIA_PLAYER_DEBUG          1
#define UNI_RECOGNIZ_DEBUG              1
#define UNI_SESSIONS_DEBUG              1
#define UNI_WATCHDOG_DEBUG              1

#define EVENT_TASK                     "event_task"
#define LSR_TASK                       "lsr_task"
#define ASR_TASK                       "asr_task"
#define PLAYBACK_TASK                  "playback_task"
#define PLAYLIST_TASK                  "playlist_task"
#define THPOOL_TASK                    "thpool_task_"
#define UNI_CROW_VERSION               "v2.3.1--2025082603"

typedef enum {
  UNI_NO_ERR = 0,
  UNI_INVALID_STATE_ERR,
  UNI_OPEN_ERR,
  UNI_CLOSE_ERR,
  UNI_START_ERR,
  UNI_STOP_ERR,
  UNI_DEST_ERR,
  UNI_SUSP_ERR,
  UNI_THREAD_ERR,
  UNI_INVALID_HANDLE_ERR,
  UNI_INVALID_FILE_ERR,
  UNI_INVALID_SIZE_ERR,
  UNI_INVALID_FORMAT_ERR,
  UNI_INVALID_PARAM_ERR,
  UNI_NO_CMD_ERR,
  UNI_NO_MEM_ERR,
  UNI_NO_SUPPORT_ERR,
  UNI_MODULE_INIT_ERR,
  UNI_MODULE_UNINIT_ERR,
  UNI_MODULE_INIT_ALREADY_ERR,
  UNI_MODULE_BUSY_ERR,
  UNI_MODULE_NONE_ERR,
  UNI_INVALID_USERNAME_ERR,
  UNI_INVALID_PASSWORD_ERR,
  UNI_NO_PERMISION_ERR,
  UNI_GET_STATUS_ERR,
  UNI_SET_STATUS_ERR,
  UNI_ERR_NUM_END
} uni_com_err_t;

#define MEMBER_TO_STRUCT(member_ptr, \
                         type, member)    (type *)((char *)(member_ptr) - \
                                          (unsigned long)&((type *)0)->member)
#define UNI_ISSPACE(x)                    (((x) == 0x20) || ((x) > 0x8 && (x) < 0xe))
#define uni_assert                        assert
#define uni_max(a, b)                     ((a) < (b) ? (b) : (a))
#define uni_min(a, b)                     ((b) < (a) ? (b) : (a))
#define uni_abs(a, b)                     ((a) > (b) ? ((a)-(b)) : ((b)-(a)))
#define uni_printf(...)                   
#define uni_sprintf                       sprintf
#define uni_snprintf                      snprintf
#define printf                            rt_kprintf

#define uni_malloc                        rt_malloc
#define uni_free                          rt_free
#define uni_realloc                       rt_realloc

#define uni_atoi                          atoi
#define uni_atol                          atol
#define uni_strtol                        strtol
#define uni_strtoll                       strtoll
#define uni_strtof                        strtof

#define uni_memset                        memset
#define uni_memcpy                        memcpy
#define uni_memmove                       memmove
#define uni_strcat                        strcat
#define uni_strncat                       strncat
#define uni_strstr                        strstr
#define uni_strrchr                       strrchr
#define uni_strchr                        strchr
#define uni_strlen                        strlen
#define uni_strcpy                        strcpy
#define uni_strncpy                       strncpy
#define uni_strncmp                       strncmp
#define uni_strcmp                        strcmp
#define uni_strcasecmp                    strcasecmp

#define uni_isspace                       isspace

#define uni_usleep(us)                    rt_thread_mdelay((us)/1001 + 1)
#define uni_msleep(ms)                    rt_thread_mdelay(ms)
#define uni_sleep(s)                      rt_thread_mdelay((s) * 1000)

#define uni_sem_t                         rt_sem_t
int uni_sem_init(uni_sem_t *sem, unsigned int value);
#define uni_sem_post(sem_ptr)             rt_sem_release(sem_ptr)
#define uni_sem_post_isr(sem_ptr, ptr)    rt_sem_release(sem_ptr)
#define uni_sem_isr_yield(is)             
#define uni_sem_wait(sem_ptr)             rt_sem_take(sem_ptr, RT_WAITING_FOREVER)
#define uni_sem_wait_ms(sem_ptr, ms)      rt_sem_take(sem_ptr, rt_tick_from_millisecond(ms))
#define uni_sem_destroy(sem_ptr)          rt_sem_delete(sem_ptr)

/* THREAD STACK SIZE */
#define STACK_SIZE                        1024
#define STACK_SMALL_SIZE                  (STACK_SIZE * 2)
#define STACK_NORMAL_SIZE                 (STACK_SIZE * 4)
#define STACK_MIDDLE_SIZE                 (STACK_SIZE * 6)
#define STACK_LARGE_SIZE                  (STACK_SIZE * 8)

/* TASK PRIORITY */
#define OS_PRIORITY_IDLE                  RT_THREAD_PRIORITY_MAX        //idle (lowest)
#define OS_PRIORITY_LOW                   (RT_THREAD_PRIORITY_MAX - 1)  //low
#define OS_PRIORITY_NORMAL                (RT_THREAD_PRIORITY_MAX - 2)  //normal
#define OS_PRIORITY_HIGH                  (RT_THREAD_PRIORITY_MAX - 3)  //high
#define OS_PRIORITY_REALTIME              0                             //realtime (highest)

struct thread_param {
    uni_u32 stack_size;
    uni_u32 th_priority;
    char task_name[16];
};
typedef void (*start_routine)(void *);
#define uni_pthread_t                     rt_thread_t
#define uni_pthread_id()                  rt_thread_self()
int uni_pthread_create(uni_pthread_t *thread, struct thread_param *para,
                            start_routine task_func, void* arg);
#define uni_pthread_detach(th)            
int uni_pthread_destroy(uni_pthread_t th);


#define uni_mutex_t                       rt_mutex_t
int uni_pthread_mutex_init(uni_mutex_t *mutex);
#define uni_pthread_mutex_destroy(mtx_ptr) rt_mutex_delete(mtx_ptr)
#define uni_pthread_mutex_lock(mtx_ptr)    rt_mutex_take(mtx_ptr, RT_WAITING_FOREVER)
#define uni_pthread_mutex_unlock(mtx_ptr)  rt_mutex_release(mtx_ptr)

static inline uni_u32 uni_get_clock_time_ms(void) {
  rt_tick_t xTicks = rt_tick_get();
  return (uni_u32)((uni_u64)xTicks * 1000 / RT_TICK_PER_SECOND);
}

static inline uni_u32 uni_get_clock_time_sec(void) {
  rt_tick_t xTicks = rt_tick_get();
  return xTicks / RT_TICK_PER_SECOND;
}

int uni_system_init(void);

int uni_system_final(void);

void invalidate_dcache_range(unsigned long start, unsigned long stop);

void flush_dcache_range(unsigned long start, unsigned long stop);

void uni_start_hifi(void);

#ifdef __cplusplus
}
#endif
#endif
